/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package state;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
import shapes.SnazzyShape;

/**
 * A Sprite Animation consisting of one or more Poses
 * @author Andrew Gratta <andrew.gratta@stonybrook.edu>
 */
public class Animation {
    String name;
    PoseLinkedList poses;
    int width;
    int height;
    
    /**
     * 
     * @param name The name of the animation
     * @param width The width of poses in the animation
     * @param height The height of poses in the animation 
     */
    public Animation(String name, int width, int height, boolean createInitialPose)
    {
        this.name = name;
        this.width = width;
        this.height = height;
        poses = new PoseLinkedList();
        if (createInitialPose)
        {
            Pose initialPose = new Pose(width, height);
            poses.add(initialPose);
        }
    }
    
    /**
     * Moves a pose back one frame in the animation
     */
    public void shiftPoseLeft(int poseIndex)
    {
        if (poseIndex == 0)
        {
            return;
        }
        Pose pose = poses.remove(poseIndex);
        if (pose != null)
        {
            poses.add(poseIndex - 1, pose);
        }
    }
    
    /**
     * Moves a pose forward one frame in the animation
     */
    public void shiftPoseRight(int poseIndex)
    {
        if (poseIndex >= poses.size() - 1)
        {
            return;
        }
        Pose pose = poses.remove(poseIndex);
        if (pose != null)
        {
            poses.add(poseIndex + 1, pose);
        }
    }
    
    /**
     * Gets the width of the animation's poses
     * @return 
     */
    public int getWidth()
    {
        return width;
    }
    
    /**
     * Gets the height of the animation's poses
     * @return 
     */
    public int getHeight()
    {
        return width;
    }
    
    /**
     * Gets the animation's name
     */
    public String getName()
    {
        return name;
    }
    
    /**
     * Sets the width of the animation's poses
     * @param w New width
     */
    public void setWidth(int w)
    {
        width = w;
        Iterator<Pose> posesIter = poses.iterator();
        while (posesIter.hasNext())
        {
            posesIter.next().setPoseWidth(w);
        }
    }
    
    /**
     * Sets the height of the animation's poses
     * @param h New height
     */
    public void setHeight(int h)
    {
        height = h;
        Iterator<Pose> posesIter = poses.iterator();
        while (posesIter.hasNext())
        {
            posesIter.next().setPoseHeight(h);
        }
    }
    
    /**
     * Set the name of the animation
     * @param newName The new name for the animation
     */
    public void setName(String newName)
    {
        name = newName;
    }
    
    public void addPose(Pose pose)
    {
        if (pose != null)
            poses.add(pose);
    }
    
    /**
     * Returns an iterator over the animation's poses
     * @return 
     */
    public Iterator<Pose> getCircularPoseIterator()
    {
        return poses.getCircularIterator();
    }
    
    public Vector<BufferedImage> getImageStrip()
    {
        Vector<BufferedImage> images = new Vector<BufferedImage>();
        Iterator<Pose> poseIter = poses.iterator();
        while (poseIter.hasNext())
        {
            Pose pose = poseIter.next();
            BufferedImage poseImage = 
                    new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = (Graphics2D)poseImage.getGraphics();
            Iterator<SnazzyShape> shapeIter = pose.getShapesIterator();
            while (shapeIter.hasNext())
            {
                shapeIter.next().render(g2d, 0, 0, 1, false);
            }
            images.add(poseImage);
        }
        return images;
    }
    
    /**
     * Gets the number of poses in this animation
     * @return 
     */
    public int getPoseCount()
    {
        return poses.size();
    }
    
    /**
     * Returns the default iterator for the list of poses. (Non-circular)
     * @return 
     */
    public Iterator<Pose> getPoseIterator()
    {
        return poses.iterator();
    }
    
    /**
     * Get the pose at the specified index in the animation
     * @param index Must be a number greater than or equal to 0
     * @return Returns a pose if found, otherwise returns null
     */
    public Pose getPose(int index)
    {
        if (index < 0 || index >= poses.size())
        {
            return null;
        }
        return poses.get(index);
    }
    
    public void deletePose(Pose pose)
    {
        if (poses.size() == 1)
        {
            Pose p = poses.get(0);
            if (p != null)
            {
                p.reset();
            }
        }
        else
        {
            poses.remove(pose);
        }
    }
    
    public Animation clone()
    {
        Animation clone = new Animation(name, width, height, true);
        for (Pose pose : poses)
        {
            clone.poses.add(pose.clone());
        }
        return clone;
    }
}
